<template>
  <base-modal :title="title" @closed="reset" :show.sync="visible" :width="width" class="batch-editing-customer-dialog">

    <batch-form v-if="visible" v-loading="loading" :fields="fields" ref="batchForm" :product-type-tree="productTypeTree" :default-address="config.defaultAddress"/>

    <div slot="footer" class="dialog-footer">
      <el-button @click="visible = false">{{$t('common.base.cancel')}}</el-button>
      <el-button type="primary" @click="onSubmit" :disabled="pending">{{$t('common.base.confirm')}}</el-button>
    </div>
    
    <biz-product-type-relation-modify-dialog @success="onBatchModifyProductTypeSuccessHandler" @notModify="batchEditSubmit" :quality-rule-form="qualityRuleFormData" ref="BizProductTypeRelationModifyDialog" />
    
  </base-modal>
</template>

<script>
import i18n from '@src/locales';
import { FormFieldMap, } from "@src/component/form/components";
import * as Utils from "@src/component/form/util";
import { editBatchProduct } from "@src/api/ProductApi";
import FormItem from "@src/component/form/FormItem.vue";
import * as CustomerApi from "@src/api/CustomerApi";
// import {searchCustomer} from '@src/api/EcSearchApi.js';
import { getTreeList } from '@src/api/ProductV2Api'
/* util */
import { isFunction } from '@src/util/type'
import { filterProperty, stringify } from '@src/util/lang/object.ts'
/* service */
import { isProductTypeNotValidateField } from '@service/ProductTypeService.ts'
import { isQualityTimeField, isQualityRuleStartTimeField } from '@service/FieldService.ts'
import { convertFormQualityRuleFieldValueToQualityRuleRemoteData } from '@service/QualityRuleService.ts'
/* mixin */
import ProductQualityMixin from '@src/mixins/productQualityMixin'

import { formatAddress, useFormTimezone } from 'pub-bbx-utils';
import { baseDistValueToObject } from '@src/util/addressUtil'

const { disposeFormSubmitTime } = useFormTimezone()

export default {
  name: "biz-batch-edit",
  mixins: [ProductQualityMixin],
  props: {
    title: {
      type: String,
       default: i18n.t('common.base.bulkEdit')
    },
    width: {
      type: String,
      default: '500px'
    },
    config: {
      type: Object,
      default: () => ({})
    },
    selectedIds: {
      type: Array,
      default: () => ([])
    },
    callback: Function,
  },
  data: () => {
    return {
      visible: false,
      pending: false,
      loading: false,
      productTypeTree: [],
      isProductTypeMode: false
    }
  },
  computed: {
    fields() {
      let tv = null;
      let formTypes = ["attachment", "separator", "location", "info", "autograph", "formula", "related_task"];
      let fieldNames = ["createUser", "createTime", "updateTime", "productTemplate", "tags", "remindCount", "qrcodeId", "linkmanName", "phone", "address"];
      let isNotModify = ["text", "textarea", "number"];
      let isRepeat = ["text", "textarea", "number", "phone"];

      let fields = (this.config.fields || [])
        .filter(f => formTypes.indexOf(f.formType) < 0 && !fieldNames.some(key => key === f.fieldName))
        .filter(f => !(isNotModify.indexOf(f.formType) > -1 && f.setting?.defaultValueConfig && !!f.setting.defaultValueConfig.isNotModify))
        .filter(f => !(isRepeat.indexOf(f.formType) > -1 && f.setting?.isRepeat == 1))
        .map(f => {
          tv = Object.assign({}, f);

          if (tv.formType === "select") { 
            if(tv?.setting?.selectType == 2){ 
              tv.setting.selectType = 1
            }          
          }
          
          if (tv.isSystem) {
            tv.orderId -= 100;
          }
          
          // tv.isNull = 0;
          return Object.freeze(tv);
        });

      if (!fields || !fields.length) return [];
      return fields.sort((a, b) => a.orderId - b.orderId);
    },
    productTypes() {
      return this.config.productTypes || [];
    }
  },
  mounted() {
    this.$el.addEventListener("form.add.field", this.addFieldHandler);
  },
  beforeDestroy() {
    this.$el.removeEventListener("form.add.field", this.addFieldHandler);
  },
  methods: {
    addFieldHandler(event) {
      const { detail = {} } = event
      const { field = {}, validate = null } = detail
      
      this.validate = validate
    },
    async onSubmit() {
      if (isFunction(this.validate) && await this.validate()) return;
      if (this.isProductTypeMode) {
        return this.batchEditSubmitBeforeHandler()
      }

      const params = this.buildParams();

      this.pending = true;

    //   this.$emit('submitHandler', params)

      editBatchProduct(params)
        .then(res => {
          const failure = res.status;

          this.pending = false;
          this.$platform.notification({
            type: !failure ? "success" : "error",
            title: failure ? i18n.t('component.bizBatch.editProductFail') : i18n.t('component.bizBatch.editProductSuccess'),
            message: !failure ? null : res.message
          });

          if (failure) return;
          this.visible = false;
          // this.reset();
          this.callback && this.callback();
        })
        .catch(e => console.error("e", e));
    },
    reset() {
      this.$nextTick(() => {
        this.$refs.batchForm?.reset();
        this.$refs.batchForm?.buildForm();
      })
    },
    open(isProductTypeMode = false) {

      if (!this.selectedIds.length) {
        return this.$platform.alert(i18n.t('component.bizBatch.tip'));
      }

      this.visible = true;
      this.reset();
      this.isProductTypeMode = isProductTypeMode
      
      if (isProductTypeMode) {
        this.getProductTypeTreeList()
      }
    },
    buildParams() {
      let tv = null;
      const {form, selectedField: sf} = this.$refs.batchForm.returnData()

      // 处理国际化时间转换
      const value = disposeFormSubmitTime([sf], form)
      let params = {
        mapJson: JSON.stringify({
          [sf.fieldName]: value[sf.fieldName], // 内部时间处理
        }),
        ids: this.selectedIds.join(","),
      };

      if (this.selectedFieldName === "tags") {
        params.mapJson = JSON.stringify({
          [sf.fieldName]: form[sf.fieldName].map(({id, tagName}) => ({id, tagName}))
        })
      }
      // if (sf.formType === 'user') {
      //   tv = form[sf.fieldName];

      //   params.mapJson = JSON.stringify({
      //     [sf.fieldName]: {
      //       userId: tv.userId,
      //       displayName: tv.displayName,
      //       staffId: tv.staffId
      //     },
      //   })
      // }
      if (sf.fieldName === "manager") {
        tv = form[sf.fieldName];

        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            id: tv.userId,
            name: tv.displayName,
            staffId: tv.staffId
          },
        })
      }

      if (sf.formType === "address") {
        tv = form[sf.fieldName];
        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            ...tv,
            all: formatAddress(tv,'')
          },
        })
      }
      
      // 质保规则 质保起算时间字段
      if (isQualityRuleStartTimeField(sf)) {
        params.qualityStartDate = form[sf.fieldName]
      }
      
      // 质保规则 质保时长字段
      if (isQualityTimeField(sf)) {
        let qualityRuleTimeValue = convertFormQualityRuleFieldValueToQualityRuleRemoteData(form)
        params.mapJson = stringify(filterProperty(qualityRuleTimeValue, ['qualityStartDate']))
      }
      
      return params;
    },
    getProductTypeTreeList() {
      this.loading = true
      
      getTreeList({ conData: 0 })
        .then(data => {
          if (data.success) {
            this.productTypeTree = data?.result || []
          }
        })
        .finally(err => {
          this.loading = false
        })
    },
  },
  components: {
    BatchForm: {
      name: "batch-form",
      props: {
        fields: {
          type: Array,
          default: () => ([])
        },
        defaultAddress: {
          type: Array,
          default: () => ([])
        },
        productTypeTree: {
          type: Array,
          default: () => []
        }
      },
      data:() => {
        return {
          selectedField: {},
          form: {},
          inputRemoteSearch: {
            customer: {
              options: [],
              loading: false,
            },
          },
        }
      },
      mounted() {
        this.buildForm();
      },
      methods: {
        returnData() {
          return {
            selectedField: this.selectedField,
            form: Object.assign({}, this.form),
          }
        },
        reset() {
          this.form = {};
          if(this.fields.length == 0) {
            return;
          }
          this.selectField(this.fields[0].fieldName)
        },
        dispatch({type, bubbles = false, params = {}}) {
          const _dom = Array.prototype.slice.call(this.$el.children)
            .filter(d => /form-item/g.test(d.className))[0];
          _dom.dispatchEvent(new CustomEvent(type, {detail: params, bubbles}));
        },
        buildForm() {
          if (Object.keys(this.form).length === this.fields.length) return;
          this.form = Utils.initialize(this.fields);
        },
        update(event) {
          /**
           * 选择团队使用的是单独的组件，不是统一的form组件，所以更新时的返回值不同，需要特殊处理
          */
          if (this.selectedField.fieldName === "customer") {
            this.form[this.selectedField.fieldName] = event;
            return
          }

          const f = event.field;
          this.form[f.fieldName] = event.newValue;
        },
        searchCustomer(keyword) {
          this.inputRemoteSearch.customer.loading = true;
          CustomerApi.getCustomerListAsyn({keyword, pageNum: 1, })
            .then(res => {
              this.inputRemoteSearch.customer.options = res.list;
              this.inputRemoteSearch.customer.loading = false;
            })
            .catch(err => console.error("searchCustomerManager function catch err", err));
        },
        selectField(val) {
          this.selectedField = this.fields.filter(f => f.fieldName === val)[0];

          /**
             * 1、切换的字段是系统地址时，根据默认值设置
             * 2、切换字段的时候，重新注册一遍，是因为： 切换前后两个字段类型相同，不会触发字段的组件的重新注册，form-item 的 field 就不会更新，还是切换之前的 field
             */

          if (this.selectedField.formType === "address" && this.selectedField.isSystem) {
            // 国际化地址组件返回的第一个是国家，非国际化组件第一个返回的是省
            const { country, province, city, dist} = baseDistValueToObject(this.defaultAddress);


            this.form[this.selectedField.fieldName] = {
              country: country || "",
              province: province || "",
              city: city || "",
              dist: dist || ""
            }
          }

          this.dispatch({
            type: "form.add.field",
            params: {
              value: () => this.form[this.selectedField.fieldName],
              field: this.selectedField,
              fieldName: this.selectedField.fieldName
            }
          })

          this.dispatch({
            type: "form.clear.validate",
          })
        },
        renderSelector() {
          if (!this.fields) return null;
          return (
            <el-select value={this.selectedField.fieldName} placeholder={i18n.t('common.placeholder.selectNeedChangeField')} onChange={this.selectField}>
              {this.fields.map(f => (
                <el-option
                  key={f.fieldName}
                  label={f.displayName}
                  value={f.fieldName}>
                </el-option>
              ))}
            </el-select>
          )
        },

        renderInput(h) {
          const sf = this.selectedField;

          if (!sf.formType) return null;

          if (sf.fieldName === "customer") {
            return h(
              "el-select",
              {
                props: {
                  filterable: true,
                  remote: true,
                  clearable: true,
                  "remote-method": this.searchCustomer,
                  value: this.form[sf.fieldName],
                  loading: this.inputRemoteSearch.customer.loading,
                  placeholder: i18n.t('common.placeholder.inputKeyWordToSearch'),
                },
                on: {
                  input: event => {
                    this.update(event)
                    this.$forceUpdate()
                  }
                }
              },
              this.inputRemoteSearch.customer.options
                .map(op => (
                  h(
                    "el-option",
                    {
                      props: {
                        key: op.id,
                        label: op.name,
                        value: op.id,
                      }
                    }
                  )
                )),
            )
          }
          
          const comp = FormFieldMap.get(sf.formType);
          const extendComponent = comp?.extend?.[`${sf.formType}_${sf.fieldName}_search`]
          const componentName = extendComponent || comp.build
          
          const data = {
            props: {
              field: sf,
              value: this.form[sf.fieldName],
              placeholder: Utils.genPlaceholder(sf),
              tree: this.productTypeTree
            },
            on: {
              update: event => this.update(event)
            }
          };

          // if (sf.formType === 'address' && !sf.isSystem) {
          //   data.props.disableMap = true;
          // }
          
          return h(componentName, data);
        }
      },
      render(h) {
        return (
          <div>
            <div class="item">
              <label class="form-name">{i18n.t('component.bizBatch.formName')}</label>
              <div>{this.renderSelector()}</div>
            </div>
            <form-item label={i18n.t('component.bizBatch.formLabel')}>
              {this.renderInput(h)}
            </form-item>
          </div>
        )
      }
    },
    components: {
      [FormItem.name]: FormItem,
    }
  }

}
</script>

<style lang="scss">

  .batch-editing-customer-dialog {

    .base-modal-body {
      padding: 10px 30px 0;
    }

    .form-name, .form-item label {
      width: 70px;
      padding: 0;
      line-height: 32px;
      margin-bottom: 10px;
    }

    .el-select {
      width: 100%;
    }

    .item {
      display: flex;
      justify-content: space-between;
      line-height: 32px;
      div {
        flex-grow: 1;
        .el-select {
          width: 100%;
        }
      }
    }

    .dialog-footer {
      display: flex;
      justify-content: flex-end;
    }

  }

</style>